package wiiusej.apptest.activityTasks;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import wiiusej.Wiimote;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class ComClient implements Runnable{

	
	private static String ipServer = "192.168.20.5";
	private static int portServer = 8001;
	
	private static Socket clientSocket; 
	private static PrintWriter out2 = null;
	private static BufferedReader in2 = null;
	private static String message = new String();
	private static String serverMessage = new String();	
	
	private BlockingQueue<Spell> fromEnergy;
	
	private  Vector<Spell> wiimoteSpellConfirmations = new Vector<Spell>(); 
	
	private static Logger fileLogger;
	
	private static String myMessage = "HELLO";
	
	private HashMap<Integer, Wiimote> wiimotes; 
	
	public ComClient(BlockingQueue<Spell> fromEnergy, HashMap<Integer, Wiimote> wiimotes) {
		
		
		this.fromEnergy = fromEnergy;		
		this.wiimotes = wiimotes;
		
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("comClient");
		
		
		
	}
	
	protected static Socket openConnection(String host,int Port){
		int port = Port;
		String IP = host;
	
		Socket s = null;
	
		try {
			s = new Socket(IP, port);   	       
	   
		} catch (UnknownHostException e) {
			fileLogger.info("[WIIMOTE:ERROR] Don't know about host: " + IP + ":"+port+".");
		} catch (IOException e) {
			fileLogger.info("[WIIMOTE:ERROR] Couldn't get I/O for " +
	                       "the connection to: " + IP + ":"+port+".");
		}	
		
		return s;
	}
	
	protected static void sendMessage(String message) throws IOException{
		
		fileLogger.info("[CLIENT_MSG]: " + message);
		out2.println(message);
		out2.flush();                       
	}
	
	protected static String receiveMessageWP() throws IOException{
		String line = new String();
		try{			
			line = in2.readLine();
		}
		catch(Exception e){			
			e.printStackTrace();			
		}		
		return line;		
	}


	private void initStructure(){
		
		// Opening the connection
		clientSocket = openConnection(ipServer,portServer);
				
		if (clientSocket == null) {				
			fileLogger.info("Socket: " + clientSocket);
		}else{
			fileLogger.info("Socket: " + " Port: " + clientSocket.getPort()
					+ " Address: " + clientSocket.getInetAddress());
		}
		
		
		try {			
			in2 = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			out2 = new PrintWriter(clientSocket.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		/*
		try {
			
			fileLogger.info("Sending to server... ");
			
			//sendMessage(myMessage);
				
			fileLogger.info("Wainting for server.... " );
			serverMessage = receiveMessageWP();
			fileLogger.info("[SERVER]: " + serverMessage);
			
		} catch (IOException e) {
			e.printStackTrace();
		}*/
		
		
	}
	
	
	@Override
	public void run() {
		
		initStructure();
		
		while(true){
			
			int i;
			
			try {
				
								
				fileLogger.info("Waiting for the Energy Controller");
				
				Spell castedSpell = fromEnergy.take();
				
				fileLogger.info("SPELL RECEIVED: " + castedSpell.getSpellEnergy() + 
						" from: " + castedSpell.getMyWiimote());
				
				addConfirmation(castedSpell);
				
				if(synchronizeSpells()){
					//we must send the message to the server
					
					fileLogger.info("SPELL SYNCRONIZED");
					
					try {
						//System.out.println("[CLIENTfromENERGY]: " + i);
						String msg= "spell1" + ": 20";						
						//System.out.println("[CLIENTtoSERVER]: " + msg);
						//myMessage = msg;
						
						sendMessage(msg);
						
						/*
						serverMessage = receiveMessageWP();
						fileLogger.info("[SERVER]: " + serverMessage);*/
						
						uploadConfirmations();
							
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					
				}				
				
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
			
		}		
		
	}
	
	private void uploadConfirmations(){
		if(!wiimoteSpellConfirmations.isEmpty()){
			fileLogger.info("CLERAGIN CONFIRMAITONS");
			wiimoteSpellConfirmations.clear();			
		}
		
		
	}
	private void addConfirmation(Spell castedSpell){		
		
		if(!wiimoteSpellConfirmations.contains(castedSpell.getMyWiimote())){
			fileLogger.info("Adding Conformation From: " + castedSpell.getMyWiimote() + 
					"WiimoteConfirmations: " + wiimoteSpellConfirmations.size());
			
			wiimoteSpellConfirmations.add(castedSpell);			
		}		
	}
	
	
	private int calculeAvarage(){
		
		int totalEnergy = 0;
				
		for(Spell spell : wiimoteSpellConfirmations){
			totalEnergy = totalEnergy + spell.getSpellEnergy();			
		}
		
		return totalEnergy / wiimoteSpellConfirmations.size();
		
		
	}
	
	private boolean synchronizeSpells(){
		
		fileLogger.info("WiimotesConfirmations: " + wiimoteSpellConfirmations.size());
		
		if(wiimoteSpellConfirmations.size() == wiimotes.size()){
			//both has casted the spell
			return true;			
		}
		return false;
		
	}
	
}
